Introduction

This rmd. file imports oxygen and voltage data from Google sheet Data is used to plot a oxygen and voltage gradient map of the winogradsky column Exponential and linear models were used to analyze data

Loading Packages

library(tidyverse) 
library(googledrive) 
library(googlesheets4)
#library(ggplot2)
library(knitr)
library(minpack.lm)
library(broom)
library(purrr)
library(lme4)
library(patchwork)
<<<<<<< HEAD ======= >>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159

Importing from google sheet


googlesheets4::gs4_deauth()

CleanData_Oxygen <- googlesheets4::read_sheet("https://docs.google.com/spreadsheets/d/1hNakCyqPsTNRFpf1lGjoBQ-papyZ6xHKT6mcvh3LMb8/edit?pli=1&gid=842906991#gid=842906991", "CleanData_Oxygen") |>
  mutate(Sample = as.character(Sample))
✔ Reading from Microcosms.
✔ Range ''CleanData_Oxygen''.
kable(CleanData_Oxygen) 
Sample Depth_cm DO_µg_L temp_C
1004 0.0 276.0 21.2
1004 6.2 276.0 21.2
1004 8.4 275.0 21.2
1004 13.1 6.3 21.2
1004 22.0 3.4 21.2
1003 0.0 101.0 20.0
1003 5.8 62.0 20.0
1003 8.4 52.0 20.0
1003 13.1 29.0 20.0
1003 21.3 21.0 20.0
1002 0.0 80.0 19.8
1002 6.6 45.0 19.8
1002 9.3 26.0 19.8
1002 15.1 21.0 19.8
1002 21.9 19.0 19.8
1001_C 0.0 190.0 19.0
1001_C 6.9 106.0 19.0
1001_C 10.8 99.0 19.0
1001_C 16.6 57.0 19.0
1001_C 22.7 25.0 19.0
1001_W 0.0 103.0 19.0
1001_W 6.7 34.0 19.0
1001_W 10.2 21.0 19.0
1001_W 15.2 11.0 19.0
1001_W 22.8 8.0 19.0

googlesheets4::gs4_deauth()

CleanData_Voltage <- googlesheets4::read_sheet("https://docs.google.com/spreadsheets/d/1hNakCyqPsTNRFpf1lGjoBQ-papyZ6xHKT6mcvh3LMb8/edit?pli=1&gid=842906991#gid=842906991", "CleanData_Voltage") |>
  mutate(Sample = as.character(Sample))
✔ Reading from Microcosms.
✔ Range ''CleanData_Voltage''.
kable(CleanData_Voltage)
Sample Depth_cm Voltage_Water_10s_mv Voltage_Water_Max_mv Voltage_Tap_10s_mv Voltage_Tap_Max_mv
1004 0.0 NA NA 121.0 121.0
1004 6.2 160.2 190 -168.0 -168.0
1004 8.4 74.4 79 84.0 122.0
1004 13.1 -55.0 58 43.0 51.0
1004 22.0 -200.0 204 84.0 102.0
1003 0.0 NA NA 74.0 300.0
1003 5.8 27.0 27 -13.0 26.0
1003 8.4 59.0 83 57.0 57.0
1003 13.1 -20.0 101 -94.0 -136.0
1003 21.3 -25.0 -30 161.0 177.0
1002 0.0 NA NA 51.0 199.0
1002 6.6 -39.0 -40 13.0 30.0
1002 9.3 -4.3 30 196.0 199.0
1002 15.1 24.0 -4 16.0 25.0
1002 21.9 27.0 28 194.0 199.0
1001_C 0.0 NA NA 187.0 187.0
1001_C 6.9 -10.0 -22 76.0 300.0
1001_C 10.8 25.0 60 -2.8 -2.8
1001_C 16.6 -6.0 -23 -10.5 -3.0
1001_C 22.7 6.0 48 168.0 174.0
1001_W 0.0 NA NA 187.0 187.0
1001_W 6.7 16.0 -9 13.0 170.0
1001_W 10.2 31.0 33 -48.0 -48.0
1001_W 15.2 34.0 40 24.0 24.0
1001_W 22.8 40.0 -17 72.0 72.0

Combine O2 & Voltage data by sample & depth

Gradients <- left_join(x = CleanData_Oxygen, y = CleanData_Voltage, by = c("Sample", "Depth_cm"))

Oxygen Gradient Plot

ggplot(data = CleanData_Oxygen) +
geom_point(aes(y = DO_µg_L, x = Depth_cm)) + 
  #scale_y_reverse() +
  #labs( title= "Oxygen Gradients", caption= "Figure X. Dissolved Oxygen (DO) (µg/L) measured in four Winogradsky colums at 5 depths (cm)") 
  #+ theme(plot.caption= element_text(size = 11, hjust=0)) +
  #geom_path(aes(y = Depth_cm, x = DO_µg_L)) +
  facet_grid(cols = vars(Sample)) +
  theme_bw()

#+ scale_y_continuous(limits = c(0, 300))
#define exponential decay function for data fitting.
exp_decay <- function(x, i, mu){y = i * exp(mu * x)}


O2_nest <- CleanData_Oxygen |>  #alternate forward pipe is %>% loaded with tidyverse
  nest(.by = "Sample") |>
  mutate(DecayFit = purrr::map(data, ~nlsLM(DO_µg_L ~ exp_decay(x = Depth_cm, i, mu),
                                            data = .x)),
         DecayTidy = purrr::map(DecayFit, tidy),
         DecayParam = purrr::map(DecayFit, glance),
         DecayPredict = purrr::map(DecayFit, augment)
         )
Warning: There were 5 warnings in `mutate()`.
The first warning was:
ℹ In argument: `DecayFit = purrr::map(...)`.
Caused by warning in `nlsLM()`:
! No starting values specified for some parameters.
Initializing ‘i’, ‘mu’ to '1.'.
Consider specifying 'start' or using a selfStart model
ℹ Run ]8;;ide:run:dplyr::last_dplyr_warnings()dplyr::last_dplyr_warnings()]8;; to see the 4 remaining warnings.
 
O2_nest |>
  unnest(cols = c(DecayPredict)) |>
  ggplot() +
  geom_point(aes(x = Depth_cm, y = DO_µg_L)) +
  geom_line(aes(x = Depth_cm, y = .fitted)) +
  geom_point(aes(x = Depth_cm, y = .resid), colour = "red") +
  facet_grid(cols = vars(unlist(Sample))) +
  theme_bw()

O2_nest |>
unnest(cols = c(DecayTidy)) |>
 select(-c(data, DecayFit, DecayParam, DecayPredict)) |>
  select(-c(statistic)) |>
  pivot_wider(id_cols = Sample, names_from = term, values_from = c(estimate, std.error, p.value)) |>
  kable()
Sample estimate_i estimate_mu std.error_i std.error_mu p.value_i p.value_mu
1004 326.62310 -0.0779518 101.553081 0.0494649 0.0487222 0.2131346
1003 100.85694 -0.0833277 3.557277 0.0059295 0.0000963 0.0007804
1002 78.61257 -0.0897172 6.441339 0.0139884 0.0011845 0.0076805
1001_C 190.11905 -0.0743515 10.391455 0.0078457 0.0003563 0.0024909
1001_W 102.49196 -0.1553412 3.251191 0.0097456 0.0000701 0.0005369

Voltage Gradient Plot

<<<<<<< HEAD ======= >>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159

ggplot(data = Gradients) +
  geom_point(aes(x = Depth_cm, y = Voltage_Water_10s_mv)) + 
  facet_grid(cols = vars(Sample)) + 
  theme_bw()
<<<<<<< HEAD

=======

>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159 <<<<<<< HEAD ======= >>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159

  Linear_fit <- Gradients %>% 
  group_by(Sample) %>%
  group_modify(~ {

  linear <- lm(Voltage_Water_10s_mv ~ Depth_cm, data = .x, na.action = na.exclude)
  augment(linear, data = .x)}) %>%
  ungroup()


  Linear_fit |>   
    ggplot(aes(x = Depth_cm, y = Voltage_Water_10s_mv)) +
    geom_point() +
    geom_line(aes(y = .fitted)) +
    #Showing residuals
    #geom_point(aes(x = Depth_cm, y = .resid), colour = "red") +
    geom_segment(aes(xend = Depth_cm, yend = .fitted), color = "red") +
    facet_grid(cols = vars(unlist(Sample))) +
    theme_bw()
<<<<<<< HEAD

=======

>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159
NA
NA
<<<<<<< HEAD
 
Linear_fit_param <- Linear_fit |>
  group_by(Sample) |>
  group_modify(~ {
=======

 
 Linear_fit_results <- Linear_fit |>
   group_by(Sample) |>
   group_modify(~ {
>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159
    linear_model <- lm(Voltage_Water_10s_mv ~ Depth_cm, data = .x)
    tidy_model <- tidy(linear_model)  
    tidy_model$Sample <- unique(.x$Sample)  # Ensure Sample column is added
    return(tidy_model)  
<<<<<<< HEAD
  }) |>
  ungroup() 
======= }) |> ungroup() |> # Filter for 'Depth_cm' coefficient (we are examining Voltage in terms of Depth_cm) filter(term == "Depth_cm")
>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159
Warning: Unknown or uninitialised column: `Sample`.Warning: Unknown or uninitialised column: `Sample`.Warning: Unknown or uninitialised column: `Sample`.Warning: Unknown or uninitialised column: `Sample`.Warning: Unknown or uninitialised column: `Sample`.
Linear_fit_param <- Linear_fit_param |>
  mutate(term = str_replace(term, "\\(Intercept\\)", "I"))

Linear_fit_param |>
  select(-c(statistic)) |>
  pivot_wider(id_cols = Sample, names_from = term, values_from = c(estimate, std.error, p.value)) |>
  kable()
<<<<<<< HEAD ======= >>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159 <<<<<<< HEAD ======= >>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159
Sampleestimate_I estimate_Depth_cm std.error_I std.error_Depth_cm p.value_I p.value_Depth_cmDepth_cm DO_µg_L temp_C Voltage_Water_10s_mv Voltage_Water_Max_mv Voltage_Tap_10s_mv Voltage_Tap_Max_mv .fitted .resid .hat .sigma .cooksd .std.resid
1001_C 1.370844 0.1669583 24.814453 1.6058696 0.9609665 0.9266817
1001_W 12.287870 1.3087162 6.912976 0.4609137 0.2174605 0.1048823
1002 -51.186449 4.0159886 21.382850 1.4776076 0.1390247 0.1129043
1003 66.227753 -4.6072225 34.968252 2.5893530 0.1987344 0.2171558
1004 269.340131 -22.0877369 39.168813 2.8330251 0.0205004 0.0160561
NA
<<<<<<< HEAD

Oxygen and Voltage Gradients

=======

Oxygen vs Voltage Graphs

>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159

    Oxygen <- ggplot(data = Gradients) +
      geom_point(aes(x = Depth_cm, y = DO_µg_L)) +
      facet_grid(cols = vars(Sample)) + 
      theme_bw()

    Voltage <- ggplot(data = Gradients) +
      geom_point(aes(x = Depth_cm, y = Voltage_Water_10s_mv)) +
      facet_grid(cols = vars(Sample)) + 
      theme_bw()
      
  print(Oxygen/Voltage)
<<<<<<< HEAD

=======

>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159
NA
NA
<<<<<<< HEAD =======

ggplot(data = Gradients) +
      geom_point(aes(x = DO_µg_L, y = Voltage_Water_10s_mv)) +
      geom_smooth(aes(x = DO_µg_L, y = Voltage_Water_10s_mv), method = "lm") +
      facet_grid(cols = vars(Sample)) + 
      theme_bw()

Can only import one image at a time right now, we could choose some notable ones to display?

>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159
<<<<<<< HEAD
LS0tCnRpdGxlOiAiT3h5Z2VuJlZvbHRhZ2VfZ3JhZGllbnRzIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKLS0tCgojIEludHJvZHVjdGlvbgoKVGhpcyBybWQuIGZpbGUgaW1wb3J0cyBveHlnZW4gYW5kIHZvbHRhZ2UgZGF0YSBmcm9tIEdvb2dsZSBzaGVldApEYXRhIGlzIHVzZWQgdG8gcGxvdCBhIG94eWdlbiBhbmQgdm9sdGFnZSBncmFkaWVudCBtYXAgb2YgdGhlIHdpbm9ncmFkc2t5IGNvbHVtbiAKRXhwb25lbnRpYWwgYW5kIGxpbmVhciBtb2RlbHMgd2VyZSB1c2VkIHRvIGFuYWx5emUgZGF0YQoKIyMgTG9hZGluZyBQYWNrYWdlcyAKCmBgYHtyIGxvYWRpbmcgcGFja2FnZXN9CmxpYnJhcnkodGlkeXZlcnNlKSAKbGlicmFyeShnb29nbGVkcml2ZSkgCmxpYnJhcnkoZ29vZ2xlc2hlZXRzNCkKI2xpYnJhcnkoZ2dwbG90MikKbGlicmFyeShrbml0cikKbGlicmFyeShtaW5wYWNrLmxtKQpsaWJyYXJ5KGJyb29tKQpsaWJyYXJ5KHB1cnJyKQpsaWJyYXJ5KGxtZTQpCmxpYnJhcnkocGF0Y2h3b3JrKQpgYGAKCiMjIEltcG9ydGluZyBmcm9tIGdvb2dsZSBzaGVldAoKYGBge3IgbG9hZCBDbGVhbk94eWdlbkRhdGEgZGlyZWN0IGZyb20gZ29vZ2xlc2hlZXR9Cgpnb29nbGVzaGVldHM0OjpnczRfZGVhdXRoKCkKCkNsZWFuRGF0YV9PeHlnZW4gPC0gZ29vZ2xlc2hlZXRzNDo6cmVhZF9zaGVldCgiaHR0cHM6Ly9kb2NzLmdvb2dsZS5jb20vc3ByZWFkc2hlZXRzL2QvMWhOYWtDeXFQc1ROUkZwZjFsR2pvQlEtcGFweVo2eEhLVDZtY3ZoM0xNYjgvZWRpdD9wbGk9MSZnaWQ9ODQyOTA2OTkxI2dpZD04NDI5MDY5OTEiLCAiQ2xlYW5EYXRhX094eWdlbiIpIHw+CiAgbXV0YXRlKFNhbXBsZSA9IGFzLmNoYXJhY3RlcihTYW1wbGUpKQoKa2FibGUoQ2xlYW5EYXRhX094eWdlbikgCmBgYAoKYGBge3IgbG9hZCBDbGVhblZvbHRhZ2VEYXRhIGRpcmVjdCBmcm9tIGdvb2dsZXNoZWV0fQoKZ29vZ2xlc2hlZXRzNDo6Z3M0X2RlYXV0aCgpCgpDbGVhbkRhdGFfVm9sdGFnZSA8LSBnb29nbGVzaGVldHM0OjpyZWFkX3NoZWV0KCJodHRwczovL2RvY3MuZ29vZ2xlLmNvbS9zcHJlYWRzaGVldHMvZC8xaE5ha0N5cVBzVE5SRnBmMWxHam9CUS1wYXB5WjZ4SEtUNm1jdmgzTE1iOC9lZGl0P3BsaT0xJmdpZD04NDI5MDY5OTEjZ2lkPTg0MjkwNjk5MSIsICJDbGVhbkRhdGFfVm9sdGFnZSIpIHw+CiAgbXV0YXRlKFNhbXBsZSA9IGFzLmNoYXJhY3RlcihTYW1wbGUpKQoKa2FibGUoQ2xlYW5EYXRhX1ZvbHRhZ2UpCmBgYAoKQ29tYmluZSBPMiAmIFZvbHRhZ2UgZGF0YSBieSBzYW1wbGUgJiBkZXB0aApgYGB7ciBncmFkaWVudHNfZGZ9CkdyYWRpZW50cyA8LSBsZWZ0X2pvaW4oeCA9IENsZWFuRGF0YV9PeHlnZW4sIHkgPSBDbGVhbkRhdGFfVm9sdGFnZSwgYnkgPSBjKCJTYW1wbGUiLCAiRGVwdGhfY20iKSkKYGBgCgoKIyMgT3h5Z2VuIEdyYWRpZW50IFBsb3QKCmBgYHtyIE94eWdlbiBncmFkaWVudHN9CmdncGxvdChkYXRhID0gQ2xlYW5EYXRhX094eWdlbikgKwpnZW9tX3BvaW50KGFlcyh5ID0gRE9fwrVnX0wsIHggPSBEZXB0aF9jbSkpICsgCiAgI3NjYWxlX3lfcmV2ZXJzZSgpICsKICAjbGFicyggdGl0bGU9ICJPeHlnZW4gR3JhZGllbnRzIiwgY2FwdGlvbj0gIkZpZ3VyZSBYLiBEaXNzb2x2ZWQgT3h5Z2VuIChETykgKMK1Zy9MKSBtZWFzdXJlZCBpbiBmb3VyIFdpbm9ncmFkc2t5IGNvbHVtcyBhdCA1IGRlcHRocyAoY20pIikgCiAgIysgdGhlbWUocGxvdC5jYXB0aW9uPSBlbGVtZW50X3RleHQoc2l6ZSA9IDExLCBoanVzdD0wKSkgKwogICNnZW9tX3BhdGgoYWVzKHkgPSBEZXB0aF9jbSwgeCA9IERPX8K1Z19MKSkgKwogIGZhY2V0X2dyaWQoY29scyA9IHZhcnMoU2FtcGxlKSkgKwogIHRoZW1lX2J3KCkKIysgc2NhbGVfeV9jb250aW51b3VzKGxpbWl0cyA9IGMoMCwgMzAwKSkKYGBgCgpgYGB7ciBkZWNheSBmaXRzfQojZGVmaW5lIGV4cG9uZW50aWFsIGRlY2F5IGZ1bmN0aW9uIGZvciBkYXRhIGZpdHRpbmcuCmV4cF9kZWNheSA8LSBmdW5jdGlvbih4LCBpLCBtdSl7eSA9IGkgKiBleHAobXUgKiB4KX0KCgpPMl9uZXN0IDwtIENsZWFuRGF0YV9PeHlnZW4gfD4gICNhbHRlcm5hdGUgZm9yd2FyZCBwaXBlIGlzICU+JSBsb2FkZWQgd2l0aCB0aWR5dmVyc2UKICBuZXN0KC5ieSA9ICJTYW1wbGUiKSB8PgogIG11dGF0ZShEZWNheUZpdCA9IHB1cnJyOjptYXAoZGF0YSwgfm5sc0xNKERPX8K1Z19MIH4gZXhwX2RlY2F5KHggPSBEZXB0aF9jbSwgaSwgbXUpLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRhdGEgPSAueCkpLAogICAgICAgICBEZWNheVRpZHkgPSBwdXJycjo6bWFwKERlY2F5Rml0LCB0aWR5KSwKICAgICAgICAgRGVjYXlQYXJhbSA9IHB1cnJyOjptYXAoRGVjYXlGaXQsIGdsYW5jZSksCiAgICAgICAgIERlY2F5UHJlZGljdCA9IHB1cnJyOjptYXAoRGVjYXlGaXQsIGF1Z21lbnQpCiAgICAgICAgICkKCiAKYGBgCgoKYGBge3IgcGxvdCBPMiBkZWNheSBmaXRzfQpPMl9uZXN0IHw+CiAgdW5uZXN0KGNvbHMgPSBjKERlY2F5UHJlZGljdCkpIHw+CiAgZ2dwbG90KCkgKwogIGdlb21fcG9pbnQoYWVzKHggPSBEZXB0aF9jbSwgeSA9IERPX8K1Z19MKSkgKwogIGdlb21fbGluZShhZXMoeCA9IERlcHRoX2NtLCB5ID0gLmZpdHRlZCkpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gRGVwdGhfY20sIHkgPSAucmVzaWQpLCBjb2xvdXIgPSAicmVkIikgKwogIGZhY2V0X2dyaWQoY29scyA9IHZhcnModW5saXN0KFNhbXBsZSkpKSArCiAgdGhlbWVfYncoKQpgYGAKCmBgYHtyIHNob3cgZml0IHBhcmFtZXRlcnN9Ck8yX25lc3QgfD4KdW5uZXN0KGNvbHMgPSBjKERlY2F5VGlkeSkpIHw+CiBzZWxlY3QoLWMoZGF0YSwgRGVjYXlGaXQsIERlY2F5UGFyYW0sIERlY2F5UHJlZGljdCkpIHw+CiAgc2VsZWN0KC1jKHN0YXRpc3RpYykpIHw+CiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IFNhbXBsZSwgbmFtZXNfZnJvbSA9IHRlcm0sIHZhbHVlc19mcm9tID0gYyhlc3RpbWF0ZSwgc3RkLmVycm9yLCBwLnZhbHVlKSkgfD4KICBrYWJsZSgpCmBgYAoKIyMgVm9sdGFnZSBHcmFkaWVudCBQbG90CgpgYGB7ciBQbG90dGluZyBWb2x0YWdlIEdyYWRpZW50cyBpbiB3YXRlciBhdCAxMCBzZWNvbmRzfQoKZ2dwbG90KGRhdGEgPSBHcmFkaWVudHMpICsKICBnZW9tX3BvaW50KGFlcyh4ID0gRGVwdGhfY20sIHkgPSBWb2x0YWdlX1dhdGVyXzEwc19tdikpICsgCiAgZmFjZXRfZ3JpZChjb2xzID0gdmFycyhTYW1wbGUpKSArIAogIHRoZW1lX2J3KCkKYGBgCgoKYGBge3IgUGxvdHRpbmcgV2l0aCBhIGxpbmVhciBmaXR9CgogIExpbmVhcl9maXQgPC0gR3JhZGllbnRzICU+JSAKICBncm91cF9ieShTYW1wbGUpICU+JQogIGdyb3VwX21vZGlmeSh+IHsKCiAgbGluZWFyIDwtIGxtKFZvbHRhZ2VfV2F0ZXJfMTBzX212IH4gRGVwdGhfY20sIGRhdGEgPSAueCwgbmEuYWN0aW9uID0gbmEuZXhjbHVkZSkKICBhdWdtZW50KGxpbmVhciwgZGF0YSA9IC54KX0pICU+JQogIHVuZ3JvdXAoKQoKCiAgTGluZWFyX2ZpdCB8PiAgIAogICAgZ2dwbG90KGFlcyh4ID0gRGVwdGhfY20sIHkgPSBWb2x0YWdlX1dhdGVyXzEwc19tdikpICsKICAgIGdlb21fcG9pbnQoKSArCiAgICBnZW9tX2xpbmUoYWVzKHkgPSAuZml0dGVkKSkgKwogICAgI1Nob3dpbmcgcmVzaWR1YWxzCiAgICAjZ2VvbV9wb2ludChhZXMoeCA9IERlcHRoX2NtLCB5ID0gLnJlc2lkKSwgY29sb3VyID0gInJlZCIpICsKICAgIGdlb21fc2VnbWVudChhZXMoeGVuZCA9IERlcHRoX2NtLCB5ZW5kID0gLmZpdHRlZCksIGNvbG9yID0gInJlZCIpICsKICAgIGZhY2V0X2dyaWQoY29scyA9IHZhcnModW5saXN0KFNhbXBsZSkpKSArCiAgICB0aGVtZV9idygpCgoKYGBgCgoKYGBge3IgRXhhbWluaW5nIGxpbmVhciBmaXQgcGFyYW1ldGVyc30KIApMaW5lYXJfZml0X3BhcmFtIDwtIExpbmVhcl9maXQgfD4KICBncm91cF9ieShTYW1wbGUpIHw+CiAgZ3JvdXBfbW9kaWZ5KH4gewogICAgbGluZWFyX21vZGVsIDwtIGxtKFZvbHRhZ2VfV2F0ZXJfMTBzX212IH4gRGVwdGhfY20sIGRhdGEgPSAueCkKICAgIHRpZHlfbW9kZWwgPC0gdGlkeShsaW5lYXJfbW9kZWwpICAKICAgIHRpZHlfbW9kZWwkU2FtcGxlIDwtIHVuaXF1ZSgueCRTYW1wbGUpICAjIEVuc3VyZSBTYW1wbGUgY29sdW1uIGlzIGFkZGVkCiAgICByZXR1cm4odGlkeV9tb2RlbCkgIAogIH0pIHw+CiAgdW5ncm91cCgpIAoKTGluZWFyX2ZpdF9wYXJhbSA8LSBMaW5lYXJfZml0X3BhcmFtIHw+CiAgbXV0YXRlKHRlcm0gPSBzdHJfcmVwbGFjZSh0ZXJtLCAiXFwoSW50ZXJjZXB0XFwpIiwgIkkiKSkKCkxpbmVhcl9maXRfcGFyYW0gfD4KICBzZWxlY3QoLWMoc3RhdGlzdGljKSkgfD4KICBwaXZvdF93aWRlcihpZF9jb2xzID0gU2FtcGxlLCBuYW1lc19mcm9tID0gdGVybSwgdmFsdWVzX2Zyb20gPSBjKGVzdGltYXRlLCBzdGQuZXJyb3IsIHAudmFsdWUpKSB8PgogIGthYmxlKCkKIApgYGAKCiMjIE94eWdlbiBhbmQgVm9sdGFnZSBHcmFkaWVudHMKCmBgYHtyIG94eWdlbiBhbmQgdm9sdGFnZSBncmFkaWVudHN9CgogICAgT3h5Z2VuIDwtIGdncGxvdChkYXRhID0gR3JhZGllbnRzKSArCiAgICAgIGdlb21fcG9pbnQoYWVzKHggPSBEZXB0aF9jbSwgeSA9IERPX8K1Z19MKSkgKwogICAgICBmYWNldF9ncmlkKGNvbHMgPSB2YXJzKFNhbXBsZSkpICsgCiAgICAgIHRoZW1lX2J3KCkKCiAgICBWb2x0YWdlIDwtIGdncGxvdChkYXRhID0gR3JhZGllbnRzKSArCiAgICAgIGdlb21fcG9pbnQoYWVzKHggPSBEZXB0aF9jbSwgeSA9IFZvbHRhZ2VfV2F0ZXJfMTBzX212KSkgKwogICAgICBmYWNldF9ncmlkKGNvbHMgPSB2YXJzKFNhbXBsZSkpICsgCiAgICAgIHRoZW1lX2J3KCkKICAgICAgCiAgcHJpbnQoT3h5Z2VuL1ZvbHRhZ2UpCiAgCiAgCmBgYAoKCgo=
=======
LS0tDQp0aXRsZTogIk94eWdlbiZWb2x0YWdlX2dyYWRpZW50cyINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMgSW50cm9kdWN0aW9uDQoNClRoaXMgcm1kLiBmaWxlIGltcG9ydHMgb3h5Z2VuIGFuZCB2b2x0YWdlIGRhdGEgZnJvbSBHb29nbGUgc2hlZXQNCkRhdGEgaXMgdXNlZCB0byBwbG90IGEgb3h5Z2VuIGFuZCB2b2x0YWdlIGdyYWRpZW50IG1hcCBvZiB0aGUgd2lub2dyYWRza3kgY29sdW1uIA0KRXhwb25lbnRpYWwgYW5kIGxpbmVhciBtb2RlbHMgd2VyZSB1c2VkIHRvIGFuYWx5emUgZGF0YQ0KDQojTG9hZGluZyBQYWNrYWdlcyANCg0KYGBge3IgbG9hZGluZyBwYWNrYWdlc30NCmxpYnJhcnkodGlkeXZlcnNlKSANCmxpYnJhcnkoZ29vZ2xlZHJpdmUpIA0KbGlicmFyeShnb29nbGVzaGVldHM0KQ0KI2xpYnJhcnkoZ2dwbG90MikNCmxpYnJhcnkoa25pdHIpDQpsaWJyYXJ5KG1pbnBhY2subG0pDQpsaWJyYXJ5KGJyb29tKQ0KbGlicmFyeShwdXJycikNCmxpYnJhcnkobG1lNCkNCmxpYnJhcnkocGF0Y2h3b3JrKQ0KYGBgDQoNCiNJbXBvcnRpbmcgZnJvbSBnb29nbGUgc2hlZXQNCg0KYGBge3IgbG9hZCBDbGVhbk94eWdlbkRhdGEgZGlyZWN0IGZyb20gZ29vZ2xlc2hlZXR9DQoNCmdvb2dsZXNoZWV0czQ6OmdzNF9kZWF1dGgoKQ0KDQpDbGVhbkRhdGFfT3h5Z2VuIDwtIGdvb2dsZXNoZWV0czQ6OnJlYWRfc2hlZXQoImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFoTmFrQ3lxUHNUTlJGcGYxbEdqb0JRLXBhcHlaNnhIS1Q2bWN2aDNMTWI4L2VkaXQ/cGxpPTEmZ2lkPTg0MjkwNjk5MSNnaWQ9ODQyOTA2OTkxIiwgIkNsZWFuRGF0YV9PeHlnZW4iKSB8Pg0KICBtdXRhdGUoU2FtcGxlID0gYXMuY2hhcmFjdGVyKFNhbXBsZSkpDQoNCmthYmxlKENsZWFuRGF0YV9PeHlnZW4pIA0KYGBgDQoNCmBgYHtyIGxvYWQgQ2xlYW5Wb2x0YWdlRGF0YSBkaXJlY3QgZnJvbSBnb29nbGVzaGVldH0NCg0KZ29vZ2xlc2hlZXRzNDo6Z3M0X2RlYXV0aCgpDQoNCkNsZWFuRGF0YV9Wb2x0YWdlIDwtIGdvb2dsZXNoZWV0czQ6OnJlYWRfc2hlZXQoImh0dHBzOi8vZG9jcy5nb29nbGUuY29tL3NwcmVhZHNoZWV0cy9kLzFoTmFrQ3lxUHNUTlJGcGYxbEdqb0JRLXBhcHlaNnhIS1Q2bWN2aDNMTWI4L2VkaXQ/cGxpPTEmZ2lkPTg0MjkwNjk5MSNnaWQ9ODQyOTA2OTkxIiwgIkNsZWFuRGF0YV9Wb2x0YWdlIikgfD4NCiAgbXV0YXRlKFNhbXBsZSA9IGFzLmNoYXJhY3RlcihTYW1wbGUpKQ0KDQprYWJsZShDbGVhbkRhdGFfVm9sdGFnZSkNCmBgYA0KDQpDb21iaW5lIE8yICYgVm9sdGFnZSBkYXRhIGJ5IHNhbXBsZSAmIGRlcHRoDQpgYGB7ciBncmFkaWVudHNfZGZ9DQpHcmFkaWVudHMgPC0gbGVmdF9qb2luKHggPSBDbGVhbkRhdGFfT3h5Z2VuLCB5ID0gQ2xlYW5EYXRhX1ZvbHRhZ2UsIGJ5ID0gYygiU2FtcGxlIiwgIkRlcHRoX2NtIikpDQpgYGANCg0KDQojT3h5Z2VuIEdyYWRpZW50IFBsb3QNCg0KYGBge3IgT3h5Z2VuIGdyYWRpZW50c30NCmdncGxvdChkYXRhID0gQ2xlYW5EYXRhX094eWdlbikgKw0KZ2VvbV9wb2ludChhZXMoeSA9IERPX8K1Z19MLCB4ID0gRGVwdGhfY20pKSArIA0KICAjc2NhbGVfeV9yZXZlcnNlKCkgKw0KICAjbGFicyggdGl0bGU9ICJPeHlnZW4gR3JhZGllbnRzIiwgY2FwdGlvbj0gIkZpZ3VyZSBYLiBEaXNzb2x2ZWQgT3h5Z2VuIChETykgKMK1Zy9MKSBtZWFzdXJlZCBpbiBmb3VyIFdpbm9ncmFkc2t5IGNvbHVtcyBhdCA1IGRlcHRocyAoY20pIikgDQogICMrIHRoZW1lKHBsb3QuY2FwdGlvbj0gZWxlbWVudF90ZXh0KHNpemUgPSAxMSwgaGp1c3Q9MCkpICsNCiAgI2dlb21fcGF0aChhZXMoeSA9IERlcHRoX2NtLCB4ID0gRE9fwrVnX0wpKSArDQogIGZhY2V0X2dyaWQoY29scyA9IHZhcnMoU2FtcGxlKSkgKw0KICB0aGVtZV9idygpDQojKyBzY2FsZV95X2NvbnRpbnVvdXMobGltaXRzID0gYygwLCAzMDApKQ0KYGBgDQoNCmBgYHtyIGRlY2F5IGZpdHN9DQojZGVmaW5lIGV4cG9uZW50aWFsIGRlY2F5IGZ1bmN0aW9uIGZvciBkYXRhIGZpdHRpbmcuDQpleHBfZGVjYXkgPC0gZnVuY3Rpb24oeCwgaSwgbXUpe3kgPSBpICogZXhwKG11ICogeCl9DQoNCg0KTzJfbmVzdCA8LSBDbGVhbkRhdGFfT3h5Z2VuIHw+ICAjYWx0ZXJuYXRlIGZvcndhcmQgcGlwZSBpcyAlPiUgbG9hZGVkIHdpdGggdGlkeXZlcnNlDQogIG5lc3QoLmJ5ID0gIlNhbXBsZSIpIHw+DQogIG11dGF0ZShEZWNheUZpdCA9IHB1cnJyOjptYXAoZGF0YSwgfm5sc0xNKERPX8K1Z19MIH4gZXhwX2RlY2F5KHggPSBEZXB0aF9jbSwgaSwgbXUpLA0KICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkYXRhID0gLngpKSwNCiAgICAgICAgIERlY2F5VGlkeSA9IHB1cnJyOjptYXAoRGVjYXlGaXQsIHRpZHkpLA0KICAgICAgICAgRGVjYXlQYXJhbSA9IHB1cnJyOjptYXAoRGVjYXlGaXQsIGdsYW5jZSksDQogICAgICAgICBEZWNheVByZWRpY3QgPSBwdXJycjo6bWFwKERlY2F5Rml0LCBhdWdtZW50KQ0KICAgICAgICAgKQ0KDQogDQpgYGANCg0KDQpgYGB7ciBwbG90IE8yIGRlY2F5IGZpdHN9DQpPMl9uZXN0IHw+DQogIHVubmVzdChjb2xzID0gYyhEZWNheVByZWRpY3QpKSB8Pg0KICBnZ3Bsb3QoKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBEZXB0aF9jbSwgeSA9IERPX8K1Z19MKSkgKw0KICBnZW9tX2xpbmUoYWVzKHggPSBEZXB0aF9jbSwgeSA9IC5maXR0ZWQpKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBEZXB0aF9jbSwgeSA9IC5yZXNpZCksIGNvbG91ciA9ICJyZWQiKSArDQogIGZhY2V0X2dyaWQoY29scyA9IHZhcnModW5saXN0KFNhbXBsZSkpKSArDQogIHRoZW1lX2J3KCkNCmBgYA0KDQpgYGB7ciBzaG93IGZpdCBwYXJhbWV0ZXJzfQ0KTzJfbmVzdCB8Pg0KdW5uZXN0KGNvbHMgPSBjKERlY2F5VGlkeSkpIHw+DQogc2VsZWN0KC1jKGRhdGEsIERlY2F5Rml0LCBEZWNheVBhcmFtLCBEZWNheVByZWRpY3QpKSB8Pg0KICBzZWxlY3QoLWMoc3RhdGlzdGljKSkgfD4NCiAgcGl2b3Rfd2lkZXIoaWRfY29scyA9IFNhbXBsZSwgbmFtZXNfZnJvbSA9IHRlcm0sIHZhbHVlc19mcm9tID0gYyhlc3RpbWF0ZSwgc3RkLmVycm9yLCBwLnZhbHVlKSkgfD4NCiAga2FibGUoKQ0KYGBgDQoNCiMgVm9sdGFnZSBHcmFkaWVudCBQbG90DQoNCmBgYHtyIFBsb3R0aW5nIFZvbHRhZ2UgR3JhZGllbnRzIGluIHdhdGVyIGF0IDEwIHNlY29uZHN9DQoNCmdncGxvdChkYXRhID0gR3JhZGllbnRzKSArDQogIGdlb21fcG9pbnQoYWVzKHggPSBEZXB0aF9jbSwgeSA9IFZvbHRhZ2VfV2F0ZXJfMTBzX212KSkgKyANCiAgZmFjZXRfZ3JpZChjb2xzID0gdmFycyhTYW1wbGUpKSArIA0KICB0aGVtZV9idygpDQpgYGANCg0KDQpgYGB7ciBQbG90dGluZyBXaXRoIGEgbGluZWFyIGZpdH0NCg0KICBMaW5lYXJfZml0IDwtIEdyYWRpZW50cyAlPiUgDQogIGdyb3VwX2J5KFNhbXBsZSkgJT4lDQogIGdyb3VwX21vZGlmeSh+IHsNCg0KICBsaW5lYXIgPC0gbG0oVm9sdGFnZV9XYXRlcl8xMHNfbXYgfiBEZXB0aF9jbSwgZGF0YSA9IC54LCBuYS5hY3Rpb24gPSBuYS5leGNsdWRlKQ0KICBhdWdtZW50KGxpbmVhciwgZGF0YSA9IC54KX0pICU+JQ0KICB1bmdyb3VwKCkNCg0KDQogIExpbmVhcl9maXQgfD4gICANCiAgICBnZ3Bsb3QoYWVzKHggPSBEZXB0aF9jbSwgeSA9IFZvbHRhZ2VfV2F0ZXJfMTBzX212KSkgKw0KICAgIGdlb21fcG9pbnQoKSArDQogICAgZ2VvbV9saW5lKGFlcyh5ID0gLmZpdHRlZCkpICsNCiAgICAjU2hvd2luZyByZXNpZHVhbHMNCiAgICAjZ2VvbV9wb2ludChhZXMoeCA9IERlcHRoX2NtLCB5ID0gLnJlc2lkKSwgY29sb3VyID0gInJlZCIpICsNCiAgICBnZW9tX3NlZ21lbnQoYWVzKHhlbmQgPSBEZXB0aF9jbSwgeWVuZCA9IC5maXR0ZWQpLCBjb2xvciA9ICJyZWQiKSArDQogICAgZmFjZXRfZ3JpZChjb2xzID0gdmFycyh1bmxpc3QoU2FtcGxlKSkpICsNCiAgICB0aGVtZV9idygpDQoNCg0KYGBgDQoNCg0KYGBge3IgR2VuZXJhdGluZyB0aGUgbGluZWFyIG1vZGVsIGZvciB0aGUgcGxvdHN9DQogDQogTGluZWFyX2ZpdF9yZXN1bHRzIDwtIExpbmVhcl9maXQgfD4NCiAgIGdyb3VwX2J5KFNhbXBsZSkgfD4NCiAgIGdyb3VwX21vZGlmeSh+IHsNCiAgICBsaW5lYXJfbW9kZWwgPC0gbG0oVm9sdGFnZV9XYXRlcl8xMHNfbXYgfiBEZXB0aF9jbSwgZGF0YSA9IC54KQ0KICAgIHRpZHlfbW9kZWwgPC0gdGlkeShsaW5lYXJfbW9kZWwpICANCiAgICB0aWR5X21vZGVsJFNhbXBsZSA8LSB1bmlxdWUoLngkU2FtcGxlKSAgDQogICAgcmV0dXJuKHRpZHlfbW9kZWwpICANCiAgIH0pIHw+DQogIHVuZ3JvdXAoKSB8Pg0KICAjIEZpbHRlciBmb3IgJ0RlcHRoX2NtJyBjb2VmZmljaWVudCAod2UgYXJlIGV4YW1pbmluZyBWb2x0YWdlIGluIHRlcm1zIG9mIERlcHRoX2NtKQ0KICBmaWx0ZXIodGVybSA9PSAiRGVwdGhfY20iKSAgDQoNCiMgU2VsZWN0aW5nIHRvIGluY2x1ZGUgU2FtcGxlLCBlc3RpbWF0ZSBvZiBzbG9wZSwgc3RkLmVycm9yLCBhbmQgcC52YWx1ZSBpbiB0YWJsZSBvdXRwdXQNCkxpbmVhcl9maXRfcmVzdWx0cyB8Pg0KICBzZWxlY3QoU2FtcGxlLCBlc3RpbWF0ZSwgc3RkLmVycm9yLCBwLnZhbHVlKSANCiANCiNEaXNwbGF5aW5nIHRoZSB0YWJsZSBhbmQgc3BlY2lmeWluZyBzaWcgZGlnaXRzIHNob3duDQogTGluZWFyX2ZpdCB8Pg0KICBrYWJsZShkaWdpdHM9MykNCg0KYGBgDQoNCiMjIE94eWdlbiB2cyBWb2x0YWdlIEdyYXBocw0KDQpgYGB7ciBveHlnZW4gdnMgdm9sdGFnZX0NCg0KICAgIE94eWdlbiA8LSBnZ3Bsb3QoZGF0YSA9IEdyYWRpZW50cykgKw0KICAgICAgZ2VvbV9wb2ludChhZXMoeCA9IERlcHRoX2NtLCB5ID0gRE9fwrVnX0wpKSArDQogICAgICBmYWNldF9ncmlkKGNvbHMgPSB2YXJzKFNhbXBsZSkpICsgDQogICAgICB0aGVtZV9idygpDQoNCiAgICBWb2x0YWdlIDwtIGdncGxvdChkYXRhID0gR3JhZGllbnRzKSArDQogICAgICBnZW9tX3BvaW50KGFlcyh4ID0gRGVwdGhfY20sIHkgPSBWb2x0YWdlX1dhdGVyXzEwc19tdikpICsNCiAgICAgIGZhY2V0X2dyaWQoY29scyA9IHZhcnMoU2FtcGxlKSkgKyANCiAgICAgIHRoZW1lX2J3KCkNCiAgICAgIA0KICBwcmludChPeHlnZW4vVm9sdGFnZSkNCiAgDQogIA0KYGBgDQoNCg0KYGBge3IgT3h5Z2VuIGFuZCBWb2x0YWdlIHJlbGF0aW9uc2hpcH0NCg0KZ2dwbG90KGRhdGEgPSBHcmFkaWVudHMpICsNCiAgICAgIGdlb21fcG9pbnQoYWVzKHggPSBET1/CtWdfTCwgeSA9IFZvbHRhZ2VfV2F0ZXJfMTBzX212KSkgKw0KICAgICAgZ2VvbV9zbW9vdGgoYWVzKHggPSBET1/CtWdfTCwgeSA9IFZvbHRhZ2VfV2F0ZXJfMTBzX212KSwgbWV0aG9kID0gImxtIikgKw0KICAgICAgZmFjZXRfZ3JpZChjb2xzID0gdmFycyhTYW1wbGUpKSArIA0KICAgICAgdGhlbWVfYncoKQ0KDQpgYGANCg0KDQoNCg0KIyBDYW4gb25seSBpbXBvcnQgb25lIGltYWdlIGF0IGEgdGltZSByaWdodCBub3csIHdlIGNvdWxkIGNob29zZSBzb21lIG5vdGFibGUgb25lcyB0byBkaXNwbGF5Pw0KYGBge3IgZWNobz1GQUxTRSwgb3V0LndpZHRoPSIxMDAlIiwgZmlnLmNhcD0iTXkgSW1hZ2UifQ0Ka25pdHI6OmluY2x1ZGVfZ3JhcGhpY3MoIi4uL2RvY3MvU2xpZGVQaG90b3MvMTAwMV82LjZfQy5qcGciKQ0KYGBgDQoNCg==
>>>>>>> 3aa3cf52183a46ab8b522112e7770a3bf6725159